package com.gexiaobao.pigeon.ui.fragment.setting

import android.annotation.SuppressLint
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.os.Build
import android.os.Bundle
import android.view.View
import androidx.annotation.RequiresApi
import androidx.core.view.isVisible
import com.bumptech.glide.Glide
import com.facebook.drawee.backends.pipeline.Fresco
import com.gexiaobao.pigeon.R
import com.gexiaobao.pigeon.app.base.BaseFragment
import com.gexiaobao.pigeon.app.eventViewModel
import com.gexiaobao.pigeon.app.ext.Constant
import com.gexiaobao.pigeon.app.ext.initClose
import com.gexiaobao.pigeon.app.ext.showMessage
import com.gexiaobao.pigeon.app.model.param.EditSexParams
import com.gexiaobao.pigeon.app.model.param.EditUserNameParams
import com.gexiaobao.pigeon.app.rxui.tablayout.listener.GlideEngine
import com.gexiaobao.pigeon.app.util.CacheUtil
import com.gexiaobao.pigeon.app.util.ImageLoaderManager
import com.gexiaobao.pigeon.app.util.KvUtils
import com.gexiaobao.pigeon.app.util.MeSandboxFileEngine
import com.gexiaobao.pigeon.app.util.PictureUtil
import com.gexiaobao.pigeon.app.util.RxToast
import com.gexiaobao.pigeon.databinding.FragmentPersonalInfoBinding
import com.gexiaobao.pigeon.ui.dialog.RxDialogBigImage
import com.gexiaobao.pigeon.ui.dialog.RxDialogDefault
import com.gexiaobao.pigeon.viewmodel.PersonalInfoViewModel
import com.google.zxing.BarcodeFormat
import com.google.zxing.WriterException
import com.google.zxing.qrcode.QRCodeWriter
import com.luck.picture.lib.basic.PictureSelectionModel
import com.luck.picture.lib.basic.PictureSelector
import com.luck.picture.lib.config.SelectMimeType
import com.luck.picture.lib.config.SelectModeConfig
import com.luck.picture.lib.entity.LocalMedia
import com.luck.picture.lib.interfaces.OnResultCallbackListener
import com.luck.picture.lib.language.LanguageConfig
import com.luck.picture.lib.style.PictureSelectorStyle
import com.yuyh.library.imgsel.ISNav
import com.zs.easy.imgcompress.EasyImgCompress
import com.zs.easy.imgcompress.listener.OnCompressSinglePicListener
import com.zs.easy.imgcompress.util.GBMBKBUtil
import me.hgj.jetpackmvvm.ext.nav
import me.hgj.jetpackmvvm.ext.navigateAction
import me.hgj.jetpackmvvm.ext.util.setOnclickNoRepeat
import me.hgj.jetpackmvvm.util.LogUtils
import java.io.File
import java.util.regex.Matcher
import java.util.regex.Pattern


/**
 * @Author      : hxw
 * @Date        : 2023/5/31 15:33
 * @Describe    : 个人信息
 */
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
class FragmentPersonalInfo : BaseFragment<PersonalInfoViewModel, FragmentPersonalInfoBinding>() {

    private var address = ""
    private var detailAddress = ""
    private var isModifyOrFinish = false
    private var isModifyOrFinishRealName = false
    private var bitmap: Bitmap? = null

    override fun initView(savedInstanceState: Bundle?) {
        mDatabind.viewmodel = mViewModel
        mDatabind.includeBar.toolbar.initClose("个人信息") {
            nav().navigateUp()
        }
        val userId = KvUtils.decodeString(Constant.USERID)
        generateQRCode(userId) // 生成二维码并显示
        Fresco.initialize(context)
        ISNav.getInstance()
            .init { context, path, imageView -> Glide.with(context).load(path).into(imageView) }
    }

    override fun onResume() {
        super.onResume()
        showLoading(getString(R.string.loading))
        mViewModel.getUserDetail()
    }

    override fun onBindViewClick() {
        super.onBindViewClick()
        setOnclickNoRepeat(
            mDatabind.mineSettingPasswordSelect,
            mDatabind.mineSettingPhoneSelect,
            mDatabind.mineSettingAddressSelect,
            mDatabind.mineSettingSexSelect,
            mDatabind.mineSettingSex,
            mDatabind.mineSettingPasswordSelect,
            mDatabind.tvPersonalInfoModifyRealName,
            mDatabind.tvPersonalInfoModifyName,
            mDatabind.mineSettingHeaderIconSelect,
            mDatabind.MineQrCode
        ) {
            when (it) {
                mDatabind.MineQrCode -> showBigImageDialog(bitmap)
                mDatabind.mineSettingPasswordSelect -> {
                    nav().navigateAction(R.id.action_to_modify_password)
                }

                mDatabind.mineSettingPhoneSelect -> {
                    nav().navigateAction(R.id.action_to_modify_phone)
                }

                mDatabind.mineSettingAddressSelect -> {
                    nav().navigateAction(R.id.action_to_modify_address, Bundle().apply {
                        putString("address", address)
                        putString("addressDetail", detailAddress)
                    })
                }

                mDatabind.mineSettingSex, mDatabind.mineSettingSexSelect -> {
                    showSetSexDialog()
                }

                mDatabind.mineSettingPasswordSelect -> {
                    nav().navigateAction(R.id.action_to_modify_password)
                }

                mDatabind.tvPersonalInfoModifyRealName -> {
                    modifyRealName()
                }

                mDatabind.tvPersonalInfoModifyName -> {
                    modifyName()
                }

                mDatabind.mineSettingHeaderIconSelect -> {
                    selectHeadIcon()
                }
            }
        }
    }

    private fun showBigImageDialog(bitmap: Bitmap?) {
        val dialog = RxDialogBigImage(context)
        if (bitmap != null) {
            dialog.setImage(bitmap)
        }
        dialog.setFullScreen()
        dialog.show()
    }

    private fun generateQRCode(userId: String) {
        if (userId.isEmpty()) {
            LogUtils.warnInfo("UserId为空")
            return
        }
        val qrCodeWriter = QRCodeWriter()
        try {
            val bitMatrix = qrCodeWriter.encode(userId, BarcodeFormat.QR_CODE, 240, 240)
            val width = bitMatrix.width
            val height = bitMatrix.height
            bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)

            val canvas = Canvas(bitmap!!)
            canvas.drawColor(Color.WHITE)

            val paint = Paint()
            paint.isAntiAlias = true
            paint.isFilterBitmap = true
            paint.isDither = true

            for (x in 0 until width) {
                for (y in 0 until height) {
                    bitmap!!.setPixel(x, y, if (bitMatrix[x, y]) Color.BLACK else Color.WHITE)
                }
            }
        } catch (e: WriterException) {
            e.printStackTrace()
        }
    }

    private fun selectHeadIcon() {
        val selectionModel: PictureSelectionModel = PictureSelector.create(context)
            .openGallery(SelectMimeType.ofImage())
            .setSelectorUIStyle(PictureSelectorStyle())
            .setImageEngine(GlideEngine.createGlideEngine())
            .setCropEngine(PictureUtil.getCropFileEngine())
            .setCompressEngine(PictureUtil.getCompressFileEngine())
            .setSandboxFileEngine(MeSandboxFileEngine())
            .setSelectionMode(SelectModeConfig.SINGLE)
            .setCameraInterceptListener(PictureUtil.getCustomCameraEvent())
            .setPermissionDescriptionListener(PictureUtil.getPermissionDescriptionListener())
            .setPreviewInterceptListener(PictureUtil.getPreviewInterceptListener())
            .setPermissionDeniedListener(PictureUtil.getPermissionDeniedListener())
            .setQueryFilterListener { false }
            .isLoopAutoVideoPlay(false)
            .isPageSyncAlbumCount(true)
            .setLanguage(LanguageConfig.SYSTEM_LANGUAGE)
            .setQuerySortOrder("")
            .isDisplayCamera(true)
            .isOpenClickSound(true)
            .isPreviewImage(true)
            .isMaxSelectEnabledMask(true)
            .isDirectReturnSingle(true)
        selectionModel.forResult(object : OnResultCallbackListener<LocalMedia> {
            override fun onResult(result: ArrayList<LocalMedia>?) {
                if (!result.isNullOrEmpty()) {
                    // 把单张图片压缩到1024k以内 同时像素不超过1200（宽、高都不大于1200）
                    EasyImgCompress.withSinglePic(context, result[0].realPath)
                        .maxPx(1200)
                        .maxSize(1024)
                        .enableLog(true)
                        .setOnCompressSinglePicListener(object : OnCompressSinglePicListener {
                            override fun onStart() {
                                LogUtils.debugInfo("onStart")
                            }

                            override fun onSuccess(file: File) {
                                showLoading(getString(R.string.loading))
                                mViewModel.editHeadIcon(file)
                                LogUtils.debugInfo("onSuccess size = " + GBMBKBUtil.getSize(file.length()) + " getAbsolutePath= " + file.absolutePath)
                            }

                            override fun onError(error: String) {
                                LogUtils.debugInfo("onError error = $error")
                            }
                        }).start()
                }
            }

            override fun onCancel() {}
        })
    }


    private fun modifyRealName() {
        if (!isModifyOrFinishRealName) {
            mViewModel.etRealName.set(mViewModel.realName.get())
            mDatabind.tvPersonalInfoRealName.visibility = View.GONE
            mDatabind.etPersonalInfoRealName.visibility = View.VISIBLE
            mDatabind.tvPersonalInfoModifyRealName.text = "完成"
        } else {
            showLoading(getString(R.string.loading))
            val body = EditUserNameParams(realName = mViewModel.etRealName.get().trim())
            mViewModel.editRealName(body)
            mDatabind.tvPersonalInfoRealName.visibility = View.VISIBLE
            mDatabind.etPersonalInfoRealName.visibility = View.GONE
            mDatabind.tvPersonalInfoModifyRealName.text = "修改"
        }
        isModifyOrFinishRealName = !isModifyOrFinishRealName
    }

    private fun modifyName() {
        if (!isModifyOrFinish) {
            mViewModel.etUserName.set(mViewModel.userName.get())
            mDatabind.tvPersonalInfoName.visibility = View.GONE
            mDatabind.etPersonalInfoName.visibility = View.VISIBLE
            mDatabind.tvPersonalInfoModifyName.text = "完成"
        } else {
            val limitEx = "[`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？]"
            val pattern: Pattern = Pattern.compile(limitEx)
            val m: Matcher = pattern.matcher(mViewModel.etUserName.get().trim())
            when {
                m.find() -> showMessage(resources.getString(R.string.user_name_no_pass))
                else -> {
                    showLoading(getString(R.string.loading))
                    val body = EditUserNameParams(userName = mViewModel.etUserName.get().trim())
                    mViewModel.editUserName(body)
                    mDatabind.tvPersonalInfoName.visibility = View.VISIBLE
                    mDatabind.etPersonalInfoName.visibility = View.GONE
                    mDatabind.tvPersonalInfoModifyName.text = "修改"
                }
            }
        }
        isModifyOrFinish = !isModifyOrFinish
    }

    @SuppressLint("CheckResult")
    override fun createObserver() {
        super.createObserver()
        mViewModel.editGenderResult.observe(viewLifecycleOwner) {
            if (it.isSuccess) {
                /** 调用获取个人信息接口 */
                showLoading(getString(R.string.loading))
                mViewModel.getUserDetail()
            } else {
                RxToast.showToast(it.errorMsg)
            }
        }

        mViewModel.editUserNameResult.observe(viewLifecycleOwner) {
            if (it.isSuccess) {
                KvUtils.encode(Constant.USER_NAME, mViewModel.etUserName.get())
                /** 调用获取个人信息接口 */
                showLoading(getString(R.string.loading))
                mViewModel.getUserDetail()
                eventViewModel.toRefreshData.value = true
            } else {
                RxToast.showToast(it.errorMsg)
            }
        }

        mViewModel.editHeadIconResult.observe(viewLifecycleOwner) {
            if (it.isSuccess) {
                eventViewModel.headIconResult.value = true//通知头像修改成功
                showLoading(getString(R.string.loading))
                mViewModel.getUserDetail()
            } else {
                RxToast.showToast(it.errorMsg)
            }
        }

        mViewModel.userInfoResult.observe(viewLifecycleOwner) {
            dismissLoading()
            mDatabind.tvPersonalInfoModifyRealName.isVisible = !it.certificationStatus
            CacheUtil.setUser(it)
            address = it.address
            detailAddress = it.detailedAddress
            mViewModel.gender.set(if (it.gender == 1) "男" else "女")
            mViewModel.mobile.set(it.mobile)
            mViewModel.address.set((address.replace(" - ", "") + it.detailedAddress).trim())
            mViewModel.userName.set(it.name)
            mViewModel.realName.set(it.realName)

            ImageLoaderManager.loadCircleImageFall(
                context,
                it.iconUrl,
                mDatabind.mineSettingHeaderIcon,
                R.mipmap.head_default_icon
            )
        }
    }

    private fun showSetSexDialog() {
        val dialog = RxDialogDefault(context)
        dialog.setTitle("请选择性别")
        dialog.setLeftBtnContent("女")
        dialog.setRightBtnContent("男")
        dialog.setSureListener {
            val body = EditSexParams(gender = 1)
            mViewModel.editGender(body)
            dialog.dismiss()
        }
        dialog.setCancelListener {
            val body = EditSexParams(gender = 2)
            mViewModel.editGender(body)
            dialog.dismiss()
        }
        dialog.setFullScreenWidth()
        dialog.show()
    }

}